#-*- coding: UTF-8 -*-
from pyramid.httpexceptions import HTTPFound
from pyramid.security import remember
from pyramid.security import forget

from sqlalchemy import and_
from sqlalchemy import or_
from sqlalchemy.orm import eagerload


from scp.modelo.models import DBSession
from scp.modelo.Tipo_Item import Tipo_Item
from scp.modelo.Rol import Rol
from scp.modelo.Permiso import Permiso
from scp.modelo.Item import Item
from scp.modelo.Fase import Fase
from scp.modelo.ValoresCadena import ValoresCadena
from scp.modelo.ValoresNumerico import ValoresNumerico
from scp.modelo.ValoresFecha import ValoresFecha
from scp.modelo.RelacionP_H import RelacionP_H
from scp.modelo.RelacionA_S import RelacionA_S
from scp.modelo.Linea_Base import Linea_Base

from pyramid.response import Response
from pyramid.view import view_config
import json

import re

#@view_config(renderer='json')
def lineas_base(request):
	"""Método controlador encargado de la administración de las lineas base.
		URL asociada: /lineas_base/{operacion}
		operacion:
			view: retorna las lineas base de acuerdo al id de la fase
		@param request: Petición Http del cliente. 	
	"""
	
	methodRequest = request.method
		
	dicParametros = request.matchdict
	

	if dicParametros.get('operacion') == 'crear' and request.url.find('?') == -1:
		print 'respondí un diccionario normal'
		return {'content':'Hello!'}	
	
	
	session = DBSession()
	if dicParametros.get('operacion') == 'view':
		idFase = request.params['idFase']
		lineasbaseArray = []
		
		lineasbase = session.query(Linea_Base).filter_by(fase_id = idFase).all()
		for lineabase in lineasbase:
			aux = {'idLineaBase': lineabase.id, 'nro_items': lineabase.nro_items, 'estado': lineabase.estado, 'fecha_creacion': lineabase.fecha_creacion}
			lineasbaseArray.append(aux)
			
		response = Response()
		response.body = json.dumps(dict(success = True, lineas_base = lineasbaseArray))
		response.content_type = 'application/json'
		
		return response
		
	if dicParametros.get('operacion') == 'create':
		idFase = request.params['idFase']
		ids_items = json.loads(request.params['ids_items'])
		lineabase = json.loads(request.params['lineabase']).get('data')
		fecha_creacion = lineabase.get('fecha_creacion')
		
		exito = 'SI'
		response = Response()
		for idItem in ids_items:
			nombreItem = session.query(Item.nombre).filter_by(id = idItem).first()
			posiblesPadres = session.query(RelacionP_H.padre).filter_by(hijo = idItem).all()
			tienePadreActual = None
			for posiblePadre in posiblesPadres:
				tienePadreActual = session.query(Item).filter_by(id = posiblePadre[0], flagUltimo = 1, flagBorrado = 0).first()
				if tienePadreActual:
					break
					
			if tienePadreActual:
				if not (tienePadreActual.id in ids_items):
					if tienePadreActual.estado != 'BLOQUEADO':
						exito = 'NO'
						break
			'''hijo = session.query(RelacionP_H).filter_by(hijo = idItem).first()
			if hijo:
				if not (hijo.padre in ids_items):
					padre = session.query(Item).filter_by(id = hijo.padre).first()
					if padre.estado != 'BLOQUEADO':
						exito = 'NO'
						break'''
						
		if exito == 'SI':
			lineabase = Linea_Base()
			lineabase.estado = 'CERRADO'
			lineabase.fecha_creacion = fecha_creacion
			lineabase.nro_items = len(ids_items)
			lineabase.fase_id = idFase
			session.add(lineabase)
			session.flush()
			print "lineabase.id"
			print lineabase.id
			for idItem in ids_items:
				item = session.query(Item).filter_by(id = idItem).first()
				item.estado = 'BLOQUEADO'
				item.linea_base_id = lineabase.id
			response.body = json.dumps(dict(success = True))
			
		else:
			response.body = json.dumps(dict(success = False, msg = 'No se puede crear la linea base, el item ' + nombreItem[0] + ' cuyo padre es el item ' + tienePadreActual.nombre  + ' no se encuentra en una linea base!!!'))
			
		response.content_type = 'application/json'
		
		return response
		
	if dicParametros.get('operacion') == 'itemsVer':
		idLineaBase = request.params['idLineaBase']
		items = session.query(Item).filter_by(linea_base_id = idLineaBase).all()
		
		response = Response()
		
		itemsArray = []
		for item in items:
			print "item.nombre"
			print item.nombre
			revisarItem = None
			if item.flagRevisar == 1:
				revisarItem = True
			else:
				revisarItem = False
			
			aux = {'idItem':item.id, 'codItem':item.codigo, 'nombreItem':item.nombre, 'complejidadItem':item.complejidad, 'versionItem':item.version, 'estadoItem':item.estado, 'revisarItem':revisarItem }
			itemsArray.append(aux)
		
		response.body = json.dumps(dict(success = True, items = itemsArray))
		response.content_type = 'application/json'
		
		return response
	
	if dicParametros.get('operacion') == 'edit':
		tipoRelacion = request.params['tipoRelacion']
		idItemRelacionar = request.params['idItemRelacionar']
		idRelacion = request.params['idRelacion']
		idItem = request.params['idItem']
		
		response = Response()
		if tipoRelacion == 'Padre - Hijo':
			ciclo = comprobar_ciclos(idItem, idItemRelacionar)
			if (ciclo == True):
				response.body = json.dumps(dict(success = False, msg = 'No se puede editar la relacion, se formara un ciclo!!!'))
			else:
				relacionP_H = session.query(RelacionP_H).filter_by(id = idRelacion).first()
				relacionP_H.padre = idItemRelacionar
				
				response.body = json.dumps(dict(success = True))
			
		else:
			existe_relacion = session.query(RelacionA_S).filter_by(antecesor = idItemRelacionar, sucesor = idItem).first()
			if (not existe_relacion):
				relacionA_S = session.query(RelacionA_S).filter_by(id = idRelacion).first()
				relacionA_S.antecesor = idItemRelacionar

		response.content_type = 'application/json'
		
		return response
	
	if dicParametros.get('operacion') == 'romper':
		idLineaBase = request.params['idLineaBase']
		
		print ">>>id de linea base a romper"
		print idLineaBase
		
		response = Response()
		lineaBaseRomper = session.query(Linea_Base).filter_by(id = idLineaBase ).first()
		itemsLineaBaseRomper = session.query(Item).filter_by(linea_base_id = lineaBaseRomper.id ).all()
		
		exitoTotal = True
		for itemLineaBaseRomper in itemsLineaBaseRomper:
			if exitoTotal == False:
				break
			sucesoresItem = session.query(RelacionA_S.sucesor).filter_by(antecesor = itemLineaBaseRomper.id).all()	
			for sucesorItem in sucesoresItem:
				itemSucesor = session.query(Item).filter(Item.id == sucesorItem[0]).filter(Item.flagUltimo == 1).filter(Item.flagBorrado == 0).first()
				if itemSucesor is not None:
					posiblesPadres = session.query(RelacionP_H.padre).filter_by(hijo = sucesorItem[0]).all()
					tienePadreActual = None
					for posiblePadre in posiblesPadres:
						tienePadreActual = session.query(Item).filter_by(id = posiblePadre[0], flagUltimo = 1, flagBorrado = 0).first()

					if not tienePadreActual:
						exitoParcial = False
						if itemSucesor.estado == 'BLOQUEADO' or itemSucesor.estado == 'APROBADO':
							antecesores = session.query(RelacionA_S.antecesor).filter_by(sucesor = sucesorItem[0]).all()
							for antecesor in antecesores:
								itemLBDistinta = session.query(Item).filter(Item.id == antecesor[0]).filter(Item.linea_base_id != idLineaBase).first()
								if itemLBDistinta is not None:
									exitoParcial = True
									break
							if exitoParcial == False:
								exitoTotal = False
	
		if exitoTotal:
			for itemLineaBaseRomper in itemsLineaBaseRomper:
				exitoParcial = True
				if exitoTotal == False:
					break
				hijosItem = session.query(RelacionP_H.hijo).filter_by(padre = itemLineaBaseRomper.id).all()
				for hijoItem in hijosItem:
					hijoItemLBDistinta = session.query(Item).filter(Item.id == hijoItem[0]).filter(Item.linea_base_id != idLineaBase).filter(Item.flagUltimo == 1).filter(Item.flagBorrado == 0).first()
					if hijoItemLBDistinta is not None:
						exitoParcial = False
						break
				if exitoParcial == False:
					exitoTotal = False
					
			if exitoTotal:
				#rompe la linea base y elimina relaciones
				for itemLineaBaseRomper in itemsLineaBaseRomper:
					sucesoresItem = session.query(RelacionA_S.sucesor).filter_by(antecesor = itemLineaBaseRomper.id).all()
					for sucesorItem in sucesoresItem:
						itemSucesor = session.query(Item).filter_by(id = sucesorItem[0], flagUltimo = 1, flagBorrado = 0).first()
						if itemSucesor is not None:
							relacionEliminar = session.query(RelacionA_S).filter_by(antecesor = itemLineaBaseRomper.id, sucesor = itemSucesor.id).first()
							print 'relacionEliminar.id'
							print relacionEliminar.id
							session.delete(relacionEliminar)
								
					itemLineaBaseRomper.estado = 'APROBADO'
					itemLineaBaseRomper.linea_base_id = None
				lineaBaseRomper.estado = 'ABIERTO'
				response.body = json.dumps(dict(success = True))
					
			else:
				msg	= 'No se puede romper la linea base, uno de los items hijo quedara inconsistente en otra linea base'
				response.body = json.dumps(dict(success = False, msg = msg))
		else:
			msg = 'No se puede romper la linea base, uno de los items sucesores quedara inconsistente'
			response.body = json.dumps(dict(success = False, msg = msg))
			
		'''for itemLineaBaseRomper in itemsLineaBaseRomper:
			print 'itemLineaBaseRomper.id'
			print itemLineaBaseRomper.id
			sucesoresItem = session.query(RelacionA_S.sucesor).filter_by(antecesor = itemLineaBaseRomper.id).all()
			print 'sucesoresItem'
			print sucesoresItem
			for sucesorItem in sucesoresItem:
				print 'sucesorItem'
				print sucesorItem
				antecesores = session.query(RelacionA_S.antecesor).filter_by(sucesor = sucesorItem[0]).all()
				print 'antecesores'
				print antecesores
				abrir = 'NO'
				for antecesor in antecesores:
					itemLBDistinta = session.query(Item).filter(Item.id == antecesor[0]).filter(Item.linea_base_id != idLineaBase).first()
					print 'itemLBDistinta'
					print itemLBDistinta
					if itemLBDistinta is not None:	
						abrir = 'SI'
						msg = 'No se puede romper la linea base, una de las lineas base de la siguiente fase quedara inconsistente'
						break 
				
		
		if abrir == 'SI':
			for itemLineaBaseRomper in itemsLineaBaseRomper:
				hijosItem = session.query(RelacionP_H.hijo).filter_by(padre = itemLineaBaseRomper.id).all()
				for hijoItem in hijosItem:
					hijoItemLBDistinta = session.query(Item).filter(Item.id == hijoItem[0]).filter(Item.linea_base_id != idLineaBase).filter(Item.flagUltimo == 1).filter(Item.flagUltimo == 0).first()
					if hijoItemLBDistinta is not None:
						abrir = 'NO'
						antecesoresHijoItem = session.query(RelacionA_S.antecesor).filter_by(sucesor = hijoItemLBDistinta.id).all()
						for antecesorHijoItem in antecesoresHijoItem:
							antecesorExiste = session.query(Item).filter(Item.id == antecesorHijoItem[0]).filter(Item.flagUltimo == 1).filter(Item.flagBorrado == 0).first()
							if antecesorExiste is not None:
								abrir = 'SI'
								msg = 'No se puede romper la linea base, uno de los items hijo quedara en una linea base inconsistente'
								break
								
		if abrir == 'SI':
			for itemLineaBaseRomper in itemsLineaBaseRomper:
				sucesoresItem = session.query(RelacionA_S.sucesor).filter_by(antecesor = itemLineaBaseRomper.id).all()
				for sucesorItem in sucesoresItem:
					itemSucesor = session.query(Item).filter_by(id = sucesorItem[0], flagUltimo = 1, flagBorrado = 0).first()
					if itemSucesor is not None:
						relacionEliminar = session.query(RelacionA_S).filter_by(antecesor = itemLineaBaseRomper.id, sucesor = itemSucesor.id).first()
						print 'relacionEliminar.id'
						print relacionEliminar.id
						session.delete(relacionEliminar)
							
				itemLineaBaseRomper.estado = 'APROBADO'
				itemLineaBaseRomper.linea_base_id = None
			lineaBaseRomper.estado = 'ABIERTO'
			response.body = json.dumps(dict(success = True))
		else:
			response.body = json.dumps(dict(success = False, msg = msg))'''
		
		response.content_type = 'application/json'
		
		return response
		
	if dicParametros.get('operacion') == 'itemsCrear':
		idFase = request.params['idFase']
		items = session.query(Item).filter_by(fase_id = idFase, flagUltimo = 1, flagBorrado = 0, linea_base_id = None, estado = 'APROBADO').all()
		itemsArray = []
		for item in items:
			aux = {'idItem': item.id, 'nombreItem': item.nombre}
			itemsArray.append(aux)
		response = Response()
		response.body = json.dumps(dict(success = True, items = itemsArray))
		response.content_type = 'application/json'
		
		return response
